package ExpressThree;

import javax.swing.*;

public class ControlUntils {
    private final String[] identifyNameOfDriver ={"P","O","I","A"};
    private final String[] initType={"I","I","O","O"};
    private final LinkList<DCT>list_dct;//存放在队列中
    private final LinkList<COCT>list_coct;
    private final LinkList<CHCT>list_chct;
    ControlUntils(){
        list_chct=new LinkList<>();//初始化通道控制表
        list_coct=new LinkList<>();//初始化控制器控制表
        list_dct=new LinkList<>();//初始化设备表

        //初始化
        //每两个dct连接一个coct，每两个coct连接一个chct
        initDCT();
        initCOCT();
        initCHCT();
        initConnect();
    }
    void initDCT(){
        //添加控制器
        for (int i = 0, identifyNameOfDriverLength = identifyNameOfDriver.length; i < identifyNameOfDriverLength; i++) {
            //String s = identifyNameOfDriver[i];
            list_dct.add(new DCT(identifyNameOfDriver[i],initType[i]));
        }
    }
    void initCOCT(){
        //初始化coct的个数
        int len=list_dct.size();
        if(len%2==0) {
            //申请dct一半的coct
            for (int i = 0; i < len / 2; i++) {
                list_coct.add(new COCT(i));
            }
        }
        else{
            //申请dct一半多一个的coct
            for(int i=0;i<len/2+1;i++){
                list_coct.add(new COCT(i));
            }
        }
    }
    void initCHCT(){
    //初始化chct的个数
        int len=list_coct.size();
        if(len%2==0) {
            //申请dct一半的coct
            for (int i = 0; i < len / 2; i++) {
                list_chct.add(new CHCT(i));
            }
        }
        else{
            //申请dct一半多一个的coct
            for(int i=0;i<len/2+1;i++){
                list_chct.add(new CHCT(i));
            }
        }
    }
    void initConnect(){
        int index=0;
        //每两个dct连接一个coct
        for(int i=0;i<list_dct.size();i++){
            if(i%2==0){
                list_dct.get(i).setNext(list_coct.get(index));
            }
            else{
                list_dct.get(i).setNext(list_coct.get(index));
                index++;
            }
        }

        //coct链接chct，每两个连接一个chct
        index=0;
        //每两个dct链接一个coct
        for(int i=0;i<list_coct.size();i++){
            if(i%2==0){
                list_coct.get(i).setNext(list_chct.get(index));
            }
            else{
                list_coct.get(i).setNext(list_chct.get(index));
                index++;
            }
        }
    }

    void show(){
        for(int i=0;i<list_dct.size();i++){
            System.out.println(list_dct.get(i));
        }

    }
    //分配设备表
    //identifyName为申请的设备名字
    //node为申请的线程
    public void addProcess(String identifyName,ProcessNode node){
        //从dct开始
        DCT dct=null;
        for(int i=0;i<list_dct.size();i++){
            if(list_dct.get(i).getIdentifyName().equals(identifyName)){
                dct=list_dct.get(i);
                break;
            }
        }
        if(dct!=null){
            //没有被使用
            if(dct.getProcessNode() == null){
                //改为使用
                dct.setProcessNode(node);
                //分配coct
                allocateCOCT(dct,node);
            }
            else{
                //挂到等待队列中
                dct.addInTOWaiting(node);
            }
        }
        else{
            JOptionPane.showMessageDialog(null,"没有该设备");
            //System.out.println("没有该设备");
        }
    }

    public void addProcess1(String type,ProcessNode node){
        //从dct开始
        DCT dct=null;
        for(int i=0;i<list_dct.size();i++){
            if(list_dct.get(i).getType().equals(type)){
                dct=list_dct.get(i);
                if(dct.getProcessNode()==null){
                    dct=list_dct.get(i);
                    break;
                }
            }
        }
        if(dct!=null){
            //没有被使用
            if(dct.getProcessNode() == null){
                //改为使用
                dct.setProcessNode(node);
                //分配coct
                allocateCOCT(dct,node);
            }
            else{
                //挂到等待队列中
                dct.addInTOWaiting(node);
            }
        }
        else{
            JOptionPane.showMessageDialog(null,"没有该设备");
            //System.out.println("没有该设备");
        }
    }
    //分配控制器控制表
    private void allocateCOCT(DCT dct,ProcessNode node){
        //获取dct对应的coct
        COCT coct= (COCT) dct.getNext();
        //如果coct没有被使用
        if(coct.getProcessNode()==null){
            coct.setProcessNode(node);
            allocateCHCT(coct,node);//分配chct
        }
        else{
            //被使用了，分配到等待队列中
            coct.addInTOWaiting(node);
        }
    }
    //分配通道
    private void allocateCHCT(COCT coct,ProcessNode node){
        CHCT chct= (CHCT) coct.getNext();
        if(chct.getProcessNode()==null){
            chct.setProcessNode(node);//设置运行线程
        }
        else{
            chct.addInTOWaiting(node);
        }
    }
    //删除线程
    public void removeProcess(ProcessNode node){
        boolean flag=false;
        for(int i=0;i<list_dct.size();i++){
            if(list_dct.get(i).getProcessNode()!=null&&list_dct.get(i).getProcessNode().equals(node)){
                flag=true;
                //找到当前进程
                DCT dct=list_dct.get(i);//获取dct
                //等待队列判断
                if(dct.getList_waiting().size()==0){
                    dct.setProcessNode(null);//为空，设置进程为空
                }
                else{
                    //为第一个进程创建
                    dct.setProcessNode(dct.getList_waiting().remove());
                    allocateCOCT(dct,dct.getProcessNode());
                }
                //进入coct中判断
                COCT coct= (COCT) dct.getNext();
                if(coct.getProcessNode().equals(node)){
                    //如果等待队列为空
                    if(coct.getList_waiting().size()==0){
                        //设置为空
                        coct.setProcessNode(null);
                        allocateCOCT(dct,dct.getProcessNode());
                        //在判断dct队列是否为空，如果空，那么设置null，不空设置进程
                        if(dct.getList_waiting().size()==0){
                            dct.setProcessNode(null);//为空，设置进程为空
                        }
                        else{
                            //为第一个进程创建
                            dct.setProcessNode(dct.getList_waiting().remove());
                        }
                    }
                    else{
                        //coct从等待队列中放一个出来
                        coct.setProcessNode(coct.getList_waiting().remove());
                        allocateCHCT(coct,coct.getProcessNode());
                    }
                    //进入chct中判断
                    CHCT chct= (CHCT) coct.getNext();
                    if(chct.getProcessNode().equals(node)){
                        if(chct.getList_waiting().size()==0){
                            chct.setProcessNode(null);

                            //System.out.println("回收完成");
                            //分配chct
                            //allocateCHCT(coct,coct.getProcessNode());
                            if(coct.getList_waiting().size()==0){
                                //coct.setProcessNode(null);
                                allocateCOCT(dct,dct.getProcessNode());
                                if(dct.getList_waiting().size()==0){
                                    dct.setProcessNode(null);
                                }
                                else{
                                    dct.setProcessNode(dct.getList_waiting().remove());
                                }
                            }
                            else{
                                coct.setProcessNode(coct.getList_waiting().remove());
                            }
                        }
                        else{
                            //chct等待队列放一个
                            chct.setProcessNode(chct.getList_waiting().remove());
                            //把刚刚的coct中放到等待队列中
                            //allocateCHCT(coct,coct.getProcessNode());
                        }
                    }
                    else{
                        for(int j=0;j<chct.getList_waiting().size();j++){
                            if(chct.getList_waiting().get(j).equals(node)){
                                chct.getList_waiting().remove(chct.getList_waiting().get(j));
                                break;
                            }
                        }

                        //System.out.println("回收完毕");
                    }
                }
                else{
                    for(int j=0;j<coct.getList_waiting().size();j++){
                        if(coct.getList_waiting().get(j).equals(node)){
                            coct.getList_waiting().remove(node);
                            break;
                        }
                    }

                    //System.out.println("回收完毕");
                }
                break;
            }
        }
        if(!flag){
            //找不到设备
            //System.out.println("找不到该设备");
            JOptionPane.showMessageDialog(null,"找不到该设备");
        }
    }
    //添加设备
    public void addDriver(String identifyName,String type){
        boolean flag=false;
        for(int i=0;i<list_dct.size();i++){
            if(list_dct.get(i).getIdentifyName().equals(identifyName)){
                flag=true;
                break;
            }
        }
        if(!flag){
            //获取数量
            list_dct.add(new DCT(identifyName,type));
            int numberOfDCT=list_dct.size();

            //判断dct原有数量
            if(numberOfDCT%2!=0){
                //现有，奇数个，需要创建coct
                list_coct.add(new COCT(list_coct.size()));
                //把dct与coct相连
                list_dct.get(list_dct.size()-1).setNext(list_coct.get(list_coct.size()-1));

                int numberOfCOCT=list_coct.size();

                if(numberOfCOCT%2!=0){
                    //coct奇数个，得创建新的chct
                    list_chct.add(new CHCT(list_chct.size()));
                    //coct与chct连接
                }
                list_coct.get(list_coct.size()-1).setNext(list_chct.get(list_chct.size()-1));

            }
            else{
                //奇数个，创建，原有存在了coct，连接即可
                //直接相连coct，不需要其他操作
                COCT coct=list_coct.get(list_coct.size()-1);
                list_dct.get(list_dct.size()-1).setNext(coct);
            }
        }
        else{
            JOptionPane.showMessageDialog(null,"已经存在该设备");
            //System.out.println("已经存在该设备");
        }
    }
    //移除设备
    public void removeDCT(String identifyName){
        DCT dct=null;
        for(int i=0;i<list_dct.size();i++){
            if(list_dct.get(i).getIdentifyName().equals(identifyName)){
                //有该标识符
                dct=list_dct.get(i);
                break;
            }
        }
        if(dct!=null){
            if(dct.getProcessNode()==null){
                int numberOfDCT=list_dct.size();
                if(numberOfDCT%2==0){
                    //如果是偶数
                    list_dct.remove(dct);
                }
                else {
                    //dct是奇数,并且coct不是占有的需要移除coct
                    COCT coct = (COCT) dct.getNext();
                    if (coct.getProcessNode() == null) {
                        int numberOfCOCT = list_coct.size();
                        if (numberOfCOCT % 2 == 0) {
                            //如果coct是偶数
                            list_dct.remove(dct);
                            list_coct.remove(coct);
                        } else {
                            //如果coct是奇数个
                            CHCT chct = (CHCT) coct.getNext();
                            if(chct.getProcessNode()==null) {
                                list_dct.remove(dct);
                                list_coct.remove(coct);
                                list_chct.remove(chct);
                            }
                        }
                    }
                }
            }
            else{
                JOptionPane.showMessageDialog(null,"设备正在运行，无法删除");
                //System.out.println("设备正在运行，无法删除");
            }
        }
        else {
            JOptionPane.showMessageDialog(null,"没有该设备");
            //System.out.println("没有该设备");
        }
    }

    public LinkList<CHCT> getList_chct() {
        return list_chct;
    }

    public LinkList<COCT> getList_coct() {
        return list_coct;
    }

    public LinkList<DCT> getList_dct() {
        return list_dct;
    }

    public static void main(String[] args) {
        ControlUntils c=new ControlUntils();
        c.show();
        c.addDriver("P","I");
        c.addDriver("O","I");
        c.addDriver("T","O");
        c.addDriver("A","O");
        c.addDriver("B","O");
        c.show();

        System.out.println("-------------");
        c.addProcess("P",new ProcessNode("1000"));
        c.addProcess("O",new ProcessNode("1001"));
        c.show();
        System.out.println("-----------");
        c.removeProcess(new ProcessNode("1000"));
        c.show();
    }
}
